package com.yupi.yuso.designpattern.facade;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.yuso.common.ErrorCode;
import com.yupi.yuso.designpattern.adapter.DataSourceTarget;
import com.yupi.yuso.designpattern.adapter.PictureDataSourceAdapter;
import com.yupi.yuso.designpattern.adapter.PostDataSourceAdapter;
import com.yupi.yuso.designpattern.adapter.UserDataSourceAdapter;
import com.yupi.yuso.designpattern.register.DataSourceRegister;
import com.yupi.yuso.exception.BusinessException;
import com.yupi.yuso.model.dto.search.SearchRequest;
import com.yupi.yuso.model.enums.SearchTypeEnum;
import com.yupi.yuso.model.vo.PictureVO;
import com.yupi.yuso.model.vo.PostVO;
import com.yupi.yuso.model.vo.SearchVO;
import com.yupi.yuso.model.vo.UserVO;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;

/**
 * @author vvv
 * @date 2023-12-21 18 57
 * discription
 * SearchController 根据type 来搜
 * 如何保证扩展性，
 * 也就是当我们要搜索的内容是别人的接口，比如我们只能远程调用别人的接口
 * 那么如何定义同一的规范呢？
 * 方法1：在搜索服务中同一规范，然后给其他服务的接口做适配
 */
@Component
public class SearchFacade {

    @Resource
    private UserDataSourceAdapter userDataSourceAdapter;

    @Resource
    private PostDataSourceAdapter postDataSourceAdapter;

    @Resource
    private PictureDataSourceAdapter pictureDataSourceAdapter;


    public SearchVO searchAll(SearchRequest searchRequest) {
        String type = searchRequest.getType();
        // 根据类型 type 来判断是全搜呢？还是搜那个？
        SearchTypeEnum searchTypeEnum = SearchTypeEnum.getEnumByValue(type);
        if (searchTypeEnum == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // TODO 全搜 这里不够优雅
        if (type.equals(SearchTypeEnum.ALL.getValue())) {
            CompletableFuture<Page<UserVO>> userTask = CompletableFuture.supplyAsync(() -> {
                Page<UserVO> userVOPage = userDataSourceAdapter.doSearch(searchRequest);
                return userVOPage;
            });
            CompletableFuture<Page<PostVO>> postTask = CompletableFuture.supplyAsync(() -> {
                Page<PostVO> postVOPage = postDataSourceAdapter.doSearch(searchRequest);
                return postVOPage;
            });
            CompletableFuture<Page<PictureVO>> pictureTask = CompletableFuture.supplyAsync(() -> {
                Page<PictureVO> picturePage = pictureDataSourceAdapter.doSearch(searchRequest);
                return picturePage;
            });
            CompletableFuture.allOf(userTask, postTask, pictureTask).join();
            try {
                Page<PostVO> postVOPage = postTask.get();
                Page<UserVO> userVOPage = userTask.get();
                Page<PictureVO> pictureVOPage = pictureTask.get();

                SearchVO searchVO = new SearchVO();
                searchVO.setPostVOList(postVOPage.getRecords());
                searchVO.setUserVOList(userVOPage.getRecords());
                searchVO.setPictureVOList(pictureVOPage.getRecords());
                return searchVO;
            } catch (Exception e) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
        } else {
            // 通过 DataSourceRegister 拿到 对应的 适配器类
            DataSourceTarget<?> dataSource = DataSourceRegister.getDataSourceBy(type);
            Page<?> page = dataSource.doSearch(searchRequest);
            SearchVO searchVO = new SearchVO();
            searchVO.setDataList(page.getRecords());
            return searchVO;
        }
    }
}
